package service

import (
	"admin-nexus-backend/internal/dto"
	"admin-nexus-backend/internal/model"
	"errors"

	"gorm.io/gorm"
)

// 组织服务相关错误
var (
	ErrHasChildOrganization = errors.New("该组织下存在子组织，无法删除")
	ErrOrganizationHasUsers = errors.New("该组织下存在用户，无法删除")
)

// OrganizationService 组织服务
type OrganizationService struct {
	DB *gorm.DB
}

// NewOrganizationService 创建组织服务实例
func NewOrganizationService(db *gorm.DB) *OrganizationService {
	return &OrganizationService{DB: db}
}

// GetOrganizationAndChildrenIDs 获取组织及其所有子组织的ID列表
func (s *OrganizationService) GetOrganizationAndChildrenIDs(orgID uint) ([]uint, error) {
	var orgIDs []uint
	orgIDs = append(orgIDs, orgID)

	// 递归获取所有子组织ID
	var childrenOrgs []model.Organization
	if err := s.DB.Where("parent_id = ?", orgID).Find(&childrenOrgs).Error; err != nil {
		return nil, err
	}

	for _, childOrg := range childrenOrgs {
		childIDs, err := s.GetOrganizationAndChildrenIDs(childOrg.ID)
		if err != nil {
			return nil, err
		}
		orgIDs = append(orgIDs, childIDs...)
	}

	return orgIDs, nil
}

// GetOrganizationList 获取组织列表
func (s *OrganizationService) GetOrganizationList(page, pageSize int) ([]model.Organization, int64, error) {
	var organizations []model.Organization
	var total int64

	// 计算总数
	if err := s.DB.Model(&model.Organization{}).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := s.DB.Order("order_num ASC").Offset(offset).Limit(pageSize).Find(&organizations).Error; err != nil {
		return nil, 0, err
	}
	return organizations, total, nil
}

// GetOrganizationByID 根据ID获取组织
func (s *OrganizationService) GetOrganizationByID(id uint) (*model.Organization, error) {
	var organization model.Organization
	if err := s.DB.First(&organization, id).Error; err != nil {
		return nil, err
	}
	return &organization, nil
}

// CreateOrganization 创建组织
func (s *OrganizationService) CreateOrganization(req dto.CreateOrganizationRequest) (*model.Organization, error) {
	var organization model.Organization

	// 直接使用 DTO 的数据
	organization.ParentID = req.ParentID
	organization.OrgName = req.OrgName
	organization.OrgCode = req.OrgCode
	organization.OrgType = int8(req.OrgType)
	organization.OrgLevel = req.OrgLevel
	organization.ManagerID = req.ManagerID
	organization.Contact = req.Contact
	organization.Phone = req.Phone
	organization.Email = req.Email
	organization.Address = req.Address
	organization.OrderNum = req.OrderNum
	organization.Status = int8(req.Status)
	organization.Remark = req.Remark

	if err := s.DB.Create(&organization).Error; err != nil {
		return nil, err
	}
	return &organization, nil
}

// UpdateOrganization 更新组织
func (s *OrganizationService) UpdateOrganization(id uint, req dto.UpdateOrganizationRequest) (*model.Organization, error) {
	// 首先获取组织
	organization, err := s.GetOrganizationByID(id)
	if err != nil {
		return nil, err
	}

	// 直接使用 DTO 的数据
	organization.ParentID = req.ParentID
	organization.OrgName = req.OrgName
	organization.OrgCode = req.OrgCode
	organization.OrgType = int8(req.OrgType)
	organization.OrgLevel = req.OrgLevel
	organization.ManagerID = req.ManagerID
	organization.Contact = req.Contact
	organization.Phone = req.Phone
	organization.Email = req.Email
	organization.Address = req.Address
	organization.OrderNum = req.OrderNum
	organization.Status = int8(req.Status)
	organization.Remark = req.Remark

	if err := s.DB.Save(organization).Error; err != nil {
		return nil, err
	}
	return organization, nil
}

// DeleteOrganization 删除组织
func (s *OrganizationService) DeleteOrganization(id uint) error {
	// 检查是否有子组织
	var childCount int64
	if err := s.DB.Model(&model.Organization{}).Where("parent_id = ?", id).Count(&childCount).Error; err != nil {
		return err
	}
	if childCount > 0 {
		return ErrHasChildOrganization
	}

	// 检查是否有用户关联
	var userCount int64
	if err := s.DB.Model(&model.User{}).Where("org_id = ?", id).Count(&userCount).Error; err != nil {
		return err
	}
	if userCount > 0 {
		return ErrOrganizationHasUsers
	}

	return s.DB.Delete(&model.Organization{}, id).Error
}

// BuildOrganizationTree 构建组织树形结构
func (s *OrganizationService) BuildOrganizationTree() ([]model.Organization, error) {
	// 首先获取所有组织
	var organizations []model.Organization
	if err := s.DB.Order("order_num ASC").Find(&organizations).Error; err != nil {
		return nil, err
	}

	// 然后构建树
	tree := s.buildTree(organizations, 0)
	return tree, nil
}

// buildTree 内部方法，用于递归构建组织树
func (s *OrganizationService) buildTree(organizations []model.Organization, parentID uint) []model.Organization {
	var tree []model.Organization

	for _, org := range organizations {
		if org.ParentID == parentID {
			// 递归查找子组织
			children := s.buildTree(organizations, org.ID)
			if len(children) > 0 {
				org.Children = make([]*model.Organization, len(children))
				for i := range children {
					org.Children[i] = &children[i]
				}
			}
			tree = append(tree, org)
		}
	}

	return tree
}
